package com.liangsui.cmall.auth.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.liangsui.cmall.auth.feign.MemberFeignService;
import com.liangsui.cmall.auth.vo.UserOAuth2LoginAndRegisterVo;
import com.liangsui.common.constant.AuthServerConstant;
import com.liangsui.common.utils.HttpUtils;
import com.liangsui.common.utils.R;
import com.liangsui.common.vo.MemberRespVo;
import lombok.Data;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 处理社交登录请求
 */
@Controller
public class OAuth2Controller {
    @Value("${gitee.oauth.host}")
    private String host;

    @Value("${gitee.oauth.clientid}")
    private String clientId;

    @Value("${gitee.oauth.clientsecret}")
    private String clientSecret;

    @Value("${gitee.oauth.callback}")
    private String callback;

    @Autowired
    private MemberFeignService memberFeignService;

    @GetMapping(value = "/giteeLogin")
    public String giteeLogin(HttpSession session) {
        // 用于第三方应用防止CSRF攻击
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        session.setAttribute("state", uuid);

        // Step1：获取Authorization Code
        String url = "https://gitee.com/oauth/authorize?response_type=code" +
                "&client_id=" + clientId +
                "&redirect_uri=" + URLEncoder.encode(callback) +
                "&state=" + uuid +
                "&scope=user_info";
        //因为使用的是thymeleaf模板引擎，所以是无法解析一个网址的，只能重定向
        return "redirect:"+url;
    }

    @GetMapping(value = "/oauth2/gitee/success")
    public String giteeCallback(HttpServletRequest request) throws Exception {
        HttpSession session = request.getSession();
        // 得到Authorization Code
        String code = request.getParameter("code");
        // 我们放在地址中的状态码
        String state = request.getParameter("state");
        String uuid = (String) session.getAttribute("state");

        // 验证信息我们发送的状态码
        if (null != uuid) {
            // 状态码不正确，直接返回登录页面
            if (!uuid.equals(state)) {
                return "redirect:http://auth.cmall.com/login.html";
            }
        }

        Map<String, String> headers = new HashMap<>();
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");

        Map<String, String> body = new HashMap<>();

        // Step2：通过Authorization Code获取Access Token
        Map<String, String> postMap = new HashMap<>();
        postMap.put("grant_type", "authorization_code");
        postMap.put("client_id", clientId);
        postMap.put("client_secret", clientSecret);
        postMap.put("code", code);
        postMap.put("redirect_uri", callback);

        HttpResponse response = HttpUtils.doPost(host, "/oauth/token", "post", headers,  postMap, body);
        if (response.getStatusLine().getStatusCode() == 200) {
            String result = EntityUtils.toString(response.getEntity());

            Map<String, String> getMap = new HashMap<>();
            getMap.put("access_token", String.valueOf(JSONObject.parseObject(result).get("access_token")));
            HttpResponse userinfoResponse = HttpUtils.doGet(host, "/api/v5/user", "post", headers, getMap);
            if (userinfoResponse.getStatusLine().getStatusCode() == 200) {
                /**
                 * 获取到用户信息之后，就该写你自己的业务逻辑了
                 */
                JSONObject userinfo = JSONObject.parseObject(EntityUtils.toString(userinfoResponse.getEntity()));
                UserOAuth2LoginAndRegisterVo vo = new UserOAuth2LoginAndRegisterVo();
                vo.setGiteeId(String.valueOf(userinfo.get("id")));
                vo.setGiteeName((String) userinfo.get("name"));
                vo.setGiteeLogin((String) userinfo.get("login"));
                R r = memberFeignService.oauthLoginAndRegister(vo);

                MemberRespVo data = r.getData("data", new TypeReference<MemberRespVo>() {
                });

                session.setAttribute(AuthServerConstant.LOGIN_USER, data);
                return "redirect:http://cmall.com";
            } else {
                return "redirect:http://auth.cmall.com/login.html";
            }
        } else {
            return "redirect:http://auth.cmall.com/login.html";
        }
    }
}
